import { EventEmitter } from '../utils/EventEmitter';
import { ResourceManager } from '../resources/ResourceManager';
import { AudioInstance } from './AudioInstance';
import {
    AudioType,
    AudioState,
    AudioPlayOptions,
    AudioEventType,
    AudioEventData,
    AudioManagerOptions
} from './types';

/**
 * 音频管理器类
 * 管理所有音频实例的加载、播放和控制
 */
export class AudioManager extends EventEmitter {
    private resourceManager: ResourceManager;
    private instances: Map<string, AudioInstance>;
    private options: AudioManagerOptions;
    private globalVolume: number;
    private enabled: boolean;
    private unlocked: boolean;
    
    constructor(resourceManager: ResourceManager, options: Partial<AudioManagerOptions> = {}) {
        super();
        
        this.resourceManager = resourceManager;
        this.instances = new Map();
        this.options = {
            globalVolume: 1,
            enabled: true,
            autoUnlock: true,
            maxConcurrent: 8,
            poolSize: 16,
            defaultFadeIn: 0.5,
            defaultFadeOut: 0.5,
            ...options
        };
        
        this.globalVolume = this.options.globalVolume;
        this.enabled = this.options.enabled;
        this.unlocked = false;
        
        // 自动解锁音频（移动设备）
        if (this.options.autoUnlock) {
            this.setupAutoUnlock();
        }
    }
    
    /**
     * 加载音频
     */
    public async load(name: string, url: string, type: AudioType = AudioType.SOUND): Promise<AudioInstance> {
        if (this.instances.has(name)) {
            throw new Error(`Audio already exists: ${name}`);
        }
        
        try {
            // 加载音频资源
            const resource = await this.resourceManager.load({
                name,
                url,
                type: 'audio',
                cache: true
            });
            
            // 创建音频元素
            const element = new Audio(resource.url);
            element.preload = 'auto';
            
            // 创建音频实例
            const instance = new AudioInstance(name, type, element);
            
            // 设置全局音量
            instance.setVolume(this.globalVolume);
            
            // 存储实例
            this.instances.set(name, instance);
            
            // 监听实例事件
            this.setupInstanceListeners(instance);
            
            return instance;
        } catch (error) {
            throw new Error(`Failed to load audio: ${name} - ${error.message}`);
        }
    }
    
    /**
     * 播放音频
     */
    public async play(name: string, options: AudioPlayOptions = {}): Promise<void> {
        if (!this.enabled) {
            return;
        }
        
        const instance = this.instances.get(name);
        if (!instance) {
            throw new Error(`Audio not found: ${name}`);
        }
        
        // 应用全局设置
        const playOptions: AudioPlayOptions = {
            ...options,
            fadeIn: options.fadeIn ?? this.options.defaultFadeIn,
            fadeOut: options.fadeOut ?? this.options.defaultFadeOut
        };
        
        try {
            await instance.play(playOptions);
        } catch (error) {
            throw new Error(`Failed to play audio: ${name} - ${error.message}`);
        }
    }
    
    /**
     * 暂停音频
     */
    public pause(name: string): void {
        const instance = this.instances.get(name);
        if (instance) {
            instance.pause();
        }
    }
    
    /**
     * 停止音频
     */
    public stop(name: string): void {
        const instance = this.instances.get(name);
        if (instance) {
            instance.stop();
        }
    }
    
    /**
     * 设置全局音量
     */
    public setGlobalVolume(volume: number, fadeTime?: number): void {
        this.globalVolume = Math.max(0, Math.min(1, volume));
        
        // 更新所有实例的音量
        for (const instance of this.instances.values()) {
            instance.setVolume(this.globalVolume, fadeTime);
        }
        
        this.emit(AudioEventType.GLOBAL_VOLUME_CHANGE, { volume: this.globalVolume });
    }
    
    /**
     * 设置音频音量
     */
    public setVolume(name: string, volume: number, fadeTime?: number): void {
        const instance = this.instances.get(name);
        if (instance) {
            instance.setVolume(volume, fadeTime);
        }
    }
    
    /**
     * 设置播放速率
     */
    public setPlaybackRate(name: string, rate: number): void {
        const instance = this.instances.get(name);
        if (instance) {
            instance.setPlaybackRate(rate);
        }
    }
    
    /**
     * 设置循环
     */
    public setLoop(name: string, loop: boolean): void {
        const instance = this.instances.get(name);
        if (instance) {
            instance.setLoop(loop);
        }
    }
    
    /**
     * 设置静音
     */
    public setMuted(name: string, muted: boolean): void {
        const instance = this.instances.get(name);
        if (instance) {
            instance.setMuted(muted);
        }
    }
    
    /**
     * 淡入音频
     */
    public async fadeIn(name: string, duration?: number): Promise<void> {
        const instance = this.instances.get(name);
        if (instance) {
            await instance.fadeIn(duration ?? this.options.defaultFadeIn);
        }
    }
    
    /**
     * 淡出音频
     */
    public async fadeOut(name: string, duration?: number): Promise<void> {
        const instance = this.instances.get(name);
        if (instance) {
            await instance.fadeOut(duration ?? this.options.defaultFadeOut);
        }
    }
    
    /**
     * 暂停所有音频
     */
    public pauseAll(): void {
        for (const instance of this.instances.values()) {
            instance.pause();
        }
    }
    
    /**
     * 停止所有音频
     */
    public stopAll(): void {
        for (const instance of this.instances.values()) {
            instance.stop();
        }
    }
    
    /**
     * 获取音频实例
     */
    public getInstance(name: string): AudioInstance | undefined {
        return this.instances.get(name);
    }
    
    /**
     * 获取所有音频实例
     */
    public getAllInstances(): AudioInstance[] {
        return Array.from(this.instances.values());
    }
    
    /**
     * 获取正在播放的音频实例
     */
    public getPlayingInstances(): AudioInstance[] {
        return this.getAllInstances().filter(instance => instance.state === AudioState.PLAYING);
    }
    
    /**
     * 销毁音频实例
     */
    public destroy(name: string): void {
        const instance = this.instances.get(name);
        if (instance) {
            instance.destroy();
            this.instances.delete(name);
        }
    }
    
    /**
     * 销毁所有音频实例
     */
    public destroyAll(): void {
        for (const instance of this.instances.values()) {
            instance.destroy();
        }
        this.instances.clear();
    }
    
    /**
     * 启用/禁用音频系统
     */
    public setEnabled(enabled: boolean): void {
        this.enabled = enabled;
        
        if (!enabled) {
            this.stopAll();
        }
        
        this.emit(AudioEventType.ENABLED_CHANGE, { enabled });
    }
    
    /**
     * 检查音频系统是否启用
     */
    public isEnabled(): boolean {
        return this.enabled;
    }
    
    /**
     * 检查音频是否已解锁（移动设备）
     */
    public isUnlocked(): boolean {
        return this.unlocked;
    }
    
    /**
     * 设置实例事件监听器
     */
    private setupInstanceListeners(instance: AudioInstance): void {
        // 转发实例事件
        const eventTypes = [
            AudioEventType.PLAY,
            AudioEventType.PAUSE,
            AudioEventType.STOP,
            AudioEventType.END,
            AudioEventType.VOLUME_CHANGE,
            AudioEventType.RATE_CHANGE,
            AudioEventType.LOOP_CHANGE,
            AudioEventType.MUTE_CHANGE,
            AudioEventType.FADE_START,
            AudioEventType.FADE_COMPLETE,
            AudioEventType.ERROR
        ];
        
        for (const type of eventTypes) {
            instance.on(type, (data: AudioEventData) => {
                this.emit(type, data);
            });
        }
    }
    
    /**
     * 设置自动解锁（移动设备）
     */
    private setupAutoUnlock(): void {
        const unlock = () => {
            if (!this.unlocked) {
                // 创建一个短暂的音频上下文来解锁音频
                const context = new (window.AudioContext || (window as any).webkitAudioContext)();
                const source = context.createBufferSource();
                source.connect(context.destination);
                source.start(0);
                source.stop(0.001);
                
                this.unlocked = true;
                this.emit(AudioEventType.UNLOCK);
            }
        };
        
        // 监听用户交互事件
        const events = ['click', 'touchstart', 'keydown'];
        for (const event of events) {
            document.addEventListener(event, unlock, { once: true });
        }
    }
} 